/*
 *  $Id: DamageInfo.cs 1013 2010-05-09 21:53:57Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2009 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;

namespace Ragima {
    /// <summary>
    /// Информация о наносимом уроне.
    /// </summary>
    public class DamageInfo {
        public bool IsHeal, Direct, IgnoreModTaken;
        public DamageType DmgType;
        public int FullDamage;
        private int _diffReal, _diffChange;

        public DamageInfo(DamageType dmgType, int damage) {
            IsHeal = false;
            Direct = false;
            IgnoreModTaken = false;
            DmgType = dmgType;
            FullDamage = damage;
            _diffReal = 0;
            _diffChange = 0;
        }

        public int RealDamage {
            get { return FullDamage + _diffReal; }
            set { _diffReal = value - FullDamage; }
        }

        public int HealthChange {
            get { return RealDamage + _diffChange; }
            set { _diffChange = value - RealDamage; }
        }

        public virtual void CorrectDamageByTarget(AbstractObject target) {
            if (!IsHeal && (FullDamage > 0) && (!Direct || !IgnoreModTaken)) {
                FullDamage = Math.Max(FullDamage + target.Summary.GetTakenDamage(DmgType) + target.GlobalSummary.GetTakenDamage(DmgType), 0);
            }
            if (!Direct) {
                if (target.Summary.Immunes.Contains(DmgType) || (DmgType.ImmuneBySpirit && target.IsSpirit)) FullDamage = 0;
                if (FullDamage > 0) {
                    if (target.Summary.DamageAbsorbs.Contains(DmgType)) IsHeal = !IsHeal;
                }
            }
        }
    }

    public class MeleeDamageInfo: DamageInfo {
        public Creature Attacker;

        public MeleeDamageInfo(Creature attacker, int damage): base(attacker.DmgType, damage) {
            Attacker = attacker;
        }

        public override void CorrectDamageByTarget(AbstractObject target) {
            // учет условного урона (например от заклятого врага)
            FullDamage += Math.Max(Attacker.Summary.GetConditionalDamage(Attacker, target) + Attacker.GlobalSummary.GetConditionalDamage(Attacker, target), 0);

            base.CorrectDamageByTarget(target);
        }

        public static bool TryGetAttacker(DamageInfo damage, out Creature attacker) {
            if (damage is MeleeDamageInfo) {
                attacker = (damage as MeleeDamageInfo).Attacker;
                return true;
            }
            attacker = null;
            return false;
        }
    }

    public class SpellDamageInfo: DamageInfo {
        public Player Caster;
        public SpellCard Spell;

        public SpellDamageInfo(Player caster, SpellCard spell, DamageType dmgType, int damage): base(dmgType, damage) {
            Caster = caster;
            Spell = spell;
        }
    }

    public class AbilityDamageInfo: DamageInfo {
        public AbstractObject Caster;
        public AbilityCard Ability;

        public AbilityDamageInfo(AbstractObject caster, AbilityCard ability, DamageType dmgType, int damage): base(dmgType, damage) {
            Caster = caster;
            Ability = ability;
        }
    }

    public class AffectDamageInfo: DamageInfo {
        public Affect Affect;

        public AffectDamageInfo(Affect affect, DamageType dmgType, int damage): base(dmgType, damage) {
            Affect = affect;
        }
    }
}
